//! @file   lc_exception.h
//! @brief  
//! @author Sayan Chaliha
//! @date   September, 2011
//!
//! 
#ifndef _LC_EXCEPTION_H
#define _LC_EXCEPTION_H

#include "libcyan_internal.h"
#include "lc_types.h"
#include "lc_object.h"
#include "lc_forward_decl.h"
#include "lc_basic_string.h"

namespace cyan {
  class CYAN_API Exception : public Object, public ::std::exception {
  public:
    Exception()           throw();
    virtual ~Exception()  throw();

    virtual const Char* what() const throw();

    template <typename T>
    static void CYAN_NORETURN throwException(const T& e) {
#ifdef LC_EXCEPTIONS
      throw e;
#else
      UNREFERENCED_PARAMETER(e);
      ::std::abort();
#endif /* LC_EXCEPTIONS */
    }
  };

  class CYAN_API LogicException : public Exception {
  public:
    explicit LogicException(const String& str)  throw();
    virtual ~LogicException()                   throw();

    virtual const Char* what() const throw();

  private:
    String errorMessage_;
  };

  class CYAN_API DomainException : public LogicException {
  public:
    explicit DomainException(const String& str) throw();
    virtual ~DomainException()                  throw();
  };

  class CYAN_API InvalidArgumentException : public LogicException {
  public:
    explicit InvalidArgumentException(const String& str)  throw();
    virtual ~InvalidArgumentException()                   throw();
  };

  class CYAN_API LengthException : public LogicException {
  public:
    explicit LengthException(const String& str) throw();
    virtual ~LengthException()                  throw();
  };

  class CYAN_API OutOfRangeException : public LogicException {
  public:
    explicit OutOfRangeException(const String& str) throw();
    virtual ~OutOfRangeException()                  throw();
  };

  class CYAN_API RuntimeException : public Exception {
  public:
    explicit RuntimeException(const String& str)  throw();
    virtual ~RuntimeException()                   throw();

    virtual const Char* what() const throw();

  private:
    String errorMessage_;
  };

  class CYAN_API NullPointerException : public RuntimeException {
  public:
    explicit NullPointerException(const String& str)  throw();
    virtual ~NullPointerException()                   throw();
  };

  class CYAN_API OutOfMemoryException : public RuntimeException {
  public:
    explicit OutOfMemoryException(const String& str)  throw();
    virtual ~OutOfMemoryException()                   throw();
  };

  class CYAN_API InterruptException : public RuntimeException {
  public:
    explicit InterruptException(const String& str)  throw();
    virtual ~InterruptException()                   throw();
  };

  class CYAN_API TimedOutException : public RuntimeException {
  public:
    explicit TimedOutException(const String& str) throw();
    virtual ~TimedOutException()                  throw();
  };
}

#endif /* _LC_EXCEPTION_H */
